// constantes
var TVA = 19.6;
var nb_quantite_modifie = 0; // permet savoir combien de quantité sont en train d'être modifié
var liste_quantite_reel = new Array();
var liste_regles_ligne_ligne;

// permet de vider le devis de l'ensemble des articles, groupes et blocs le composants
function viderDevis() {
	$('#contenu_devis').empty();
	liste_quantite_reel = new Array();
}

// permet de transformer une chaine de caractère afin de s'en servir comme id
// paramètres :
// - s : la chaîne de caractère en question
function chaineEnId(s) {
	alert("Cette fonction n'existe plus (et ne doit plus être appelé 'chaineEnId') !");
}

// permet d'appliquer une liste de règles de type ligne/ligne sur le formulaire de la page
// ainsi, chaque ajout d'un article dans le devis peut entrainer une ou plusieurs actions
// paramètres :
// - la liste des règles constitué de la manière suivante :
// [
// 	id_article_parent
// 	id_article_enfant
// 	coef_qtte_parent
// ]
function appliquerListeRegleLigneLigne(liste_regles) {
	liste_regles_ligne_ligne = new Array();
	
	for (var k in liste_regles) {
		if(liste_regles_ligne_ligne[liste_regles[k].id_article_parent] == undefined) {
			liste_regles_ligne_ligne[liste_regles[k].id_article_parent] = new Array();
		}
		liste_regles_ligne_ligne[liste_regles[k].id_article_parent].push({id_article:liste_regles[k].id_article_enfant, coefficient:liste_regles[k].coef_qtte_parent});
	}
}

// permet d'ajouter les articles déclenché par l'ajout d'un article
// paramètres :
// - id_article : l'id de l'article qui déclenche la ou les règles
function ajouterArticlesDeclenches(id_article, quantite) {
	if(liste_regles_ligne_ligne[id_article]) {
		for (var k in liste_regles_ligne_ligne[id_article]) {
			var article = trouverArticle(liste_regles_ligne_ligne[id_article][k].id_article);
			ajouterCategorie(article.groupe.id_groupe_devis, article.groupe.libelle_groupe_devis, article.bloc.id_bloc_devis, article.bloc.libelle_bloc_devis, article.groupe.rang_groupe_devis, article.bloc.rang_bloc_devis);
			ajouterArticle({id:article.bloc.id_bloc_devis, libelle:article.bloc.libelle_bloc_devis}, {id:article.groupe.id_groupe_devis, libelle:article.groupe.libelle_groupe_devis}, {id:article.id_article, code:article.ref_article, description:article.description_article,
								quantite:liste_regles_ligne_ligne[id_article][k].coefficient*quantite, prix:article.tarif_brut,
								quantite_modifiable:true, supprimable:true}, false);
		}
	}
}

// permet de trouver un article à partir de son id.
// recherche l'article dans les categories contenu dans la variable globale 'categories'
// paramètres :
// - id_article : l'id de l'article recherché
function trouverArticle(id_article) {
	for (var k in categories) {
		if(categories[k].articles[id_article]) return categories[k].articles[id_article];
	}
	alert("Erreur : article non trouvé ("+id_article+")");
}

// permet d'ajouter un bloc au devis si il n'existe pas déjà
// paramètres :
// - id : l'id du bloc
// - nom : le nom du bloc
// - rang : le rang du bloc (classé par ordre croissant)
function ajouterBloc(id, nom, rang) {
	// on test si le bloc existe déjà
	if($('#bloc_'+id).length == 0) {
		// recherche de l'emplacement du futur bloc
		var trouver;
		$('.bloc_devis').each(function(indice, el) {
			if(!trouver) {
				var jel = $(el);
				if(rang < jel.find('input[name$="[rang]"]').val()) trouver = jel;
			}
		});
		
		// si on a pas trouver de bloc avec un rang supérieur, alors on l'ajoute à la fin
		var aLaFin = false;
		if(!trouver) {
			aLaFin = true;
			trouver = $('#contenu_devis');
		}
		
		// ajout de la categorie
		var nouveau_bloc = $(
		'<tr id="bloc_'+id+'" class="bloc_devis">'+
			'<th colspan="5" class="titre_tableau">'+nom+'<input type="hidden" name="bloc['+id+'][nom]" value="'+nom+'" /><input type="hidden" name="bloc['+id+'][rang]" value="'+rang+'" /></th>'+
		'</tr>');
		var entete_bloc = $(
		'<tr class="categorie_tableau">'+
			'<td class="soustitre_tableau">Code</td>'+
			'<td class="soustitre_tableau">Description</td>'+
			'<td class="soustitre_tableau">Prix unitaire</td>'+
			'<td class="soustitre_tableau">Quantité</td>'+
			'<td class="soustitre_tableau">Total HT</td>'+
		'</tr>');
		var montant_bloc = $(
		'<tr><td colspan="5" style="border:none; height:4px;"></td></tr>'+
		'<tr class="montant_ht empty_tr">'+
			'<td>&nbsp;</td>'+
			'<td>&nbsp;</td>'+
			'<td class="titretotal_devis" colspan="2">Montant HT</td>'+
			'<td name="montant_ht" class="titretotal_devis">0.00€</td>'+
		'<tr class="tva empty_tr">'+
			'<td>&nbsp;</td>'+
			'<td>&nbsp;</td>'+
			'<td class="titretotal_devis" colspan="2">TVA ('+TVA+'%)</td>'+
			'<td name="tva" class="titretotal_devis">0.00€</td>'+
		'</tr>'+
		'<tr class="montant_bloc empty_tr">'+
			'<td>&nbsp;</td>'+
			'<td>&nbsp;</td>'+
			'<td class="titretotal_devis" colspan="2">Total TTC</td>'+
			'<td name="montant_bloc" class="titretotal_devis">0.00€</td>'+
		'</tr>'+
		'<tr><td colspan="5" style="border:none; height:15px;"></td></tr>');
		
		
		
		if(aLaFin) trouver.append(nouveau_bloc);
		else trouver.before(nouveau_bloc);
		
		nouveau_bloc.after(entete_bloc);
		entete_bloc.after(montant_bloc);
		
		
		
		/*
		if(aLaFin) $(".montant_ht").before(nouveau_bloc);
		else trouver.before(nouveau_bloc);
		
		nouveau_bloc.after(entete_bloc);
		
		if($(".montant_ht").length < 1)
			$('#contenu_devis').append(montant_bloc);*/
	}
}

// applique les regles de type devis passer en paramètres
// paramètres :
// - regles : un tableau contenant les règles sous la forme suivante :
// 	- id_article : l'article concerné
// 	- id_reponse : la réponse conditionnant l'application de la règle
// 	- nouveau_prix : le nouveau prix à appliqué pour l'article
function appliquerReglesDevis(regles) {
	var articleChange = new Array();
	
	for (var k in regles) {
		if($("#reponse_devis_" + regles[k].id_reponse).is(':selected')) {
			changerPrixArticle(regles[k].id_article, regles[k].nouveau_tarif);
			articleChange[regles[k].id_article] = true;
		}
		else if(articleChange[regles[k].id_article] == undefined) {
			restaurerPrixArticle(regles[k].id_article);
		}
	}
	
	mettreAJourPrixDevis();
}

// permet de changer le prix d'un article
// paramètres :
// - id_article : l'id de l'article dont il faut modifier le prix
// - prix : le nouveau prix pour cet article
function changerPrixArticle(id_article, prix) {
	$('#prix_article_'+id_article).val(prix);
	$('#affichage_prix_article_'+id_article).text(prix + ' €');
}

// utilise la variable globale 'categories' pour restaurer le prix original d'un article
// paramètres :
// - id_article : l'id de l'article don ton souhaite restaurer le prix
function restaurerPrixArticle(id_article) {
	for (var k in categories) {
		if(categories[k].articles[id_article]) {
			changerPrixArticle(id_article, categories[k].articles[id_article].tarif_brut);
		}
	}
}

// permet d'ajouter une categorie au devis si elle n'existe pas déjà
// paramètres :
// - id : l'id de la categorie
// - nom : le nom de la categorie
// - nomBloc : le nom du bloc auquel ajouté la categorie
// - rang : le rang de la categorié (classé par ordre croissant)
// - rang_bloc : le rang du bloc, utilisé si on à besoin de le créer
function ajouterCategorie(id, nom, id_bloc, nomBloc, rang, rang_bloc) {
	// on recherche le bloc
	var bloc = $('#bloc_' + id);
	// si on a bien trouvé le bloc...
	if(bloc.length == 0) {
		ajouterBloc(id_bloc, nomBloc, rang_bloc);
	}
	
	// on test d'abord si la catégorie n'existe pas déjà
	if($('#bloc_'+id_bloc+'_categorie_'+id).length == 0) {
		// on recherche l'emplacement par le rang, en cherchant le rang de la categorie apres laquelle inserer
		var trouver;
		$('.categorie_tableau[id*="bloc_'+id_bloc+'_categorie_"]').each(function(indice, el) {
			var jel = $(el);
			var i = -1;
			// on cherche la categorie ayant le rang le plus proche mais inferieur au rang a inserer
			// on regarde si le rang trouver est inferieur au rang a inserer et superieur a un rang deja trouver
			// si cest le cas on met a jour ce quon a trouvé
			if(jel.find('input[name$="[rang]"]').val() < rang && jel.find('input[name$="[rang]"]').val() > i) {
				trouver = jel;
				i = jel.find('input[name$="[rang]"]').val();
			}
		});
		
		// on crée les éléments de la categorie
		var nouvelle_categorie = $(
		'<tr class="categorie_tableau" id="bloc_'+id_bloc+'_categorie_'+id+'" name="categorie">'+
			'<td class="soussoustitre_tableau"><input type="hidden" value="'+nom+'" name="categorie['+id+'][nom]" /><input type="hidden" value="'+id_bloc+'" name="categorie['+id+'][id_bloc]" /><input type="hidden" name="categorie['+id+'][rang]" value="'+rang+'" /></td>'+
			'<td class="soussoustitre_tableau">'+nom+'</td>'+
			'<td class="soussoustitre_tableau cellule_prix_unitaire"></td>'+
			'<td class="soussoustitre_tableau cellule_quantite"></td>'+
			'<td class="soussoustitre_tableau cellule_prix_total"></td>'+
		'</tr>');
		var montant_categorie = $(
		'<tr class="empty_tr montant_categorie">'+
			'<td>&nbsp;</td>'+
			'<td>&nbsp;</td>'+
			'<td colspan="2" class="titretotal_devis">Sous-Total '+nom+'</td>'+
			'<td class="total_devis" id="montant_total_categorie_'+id+'">0,00€</td>'+
		'</tr>');
		
		if(!trouver) {
			$('#bloc_'+id_bloc+' + .categorie_tableau').after(nouvelle_categorie);
		}
		else {
			trouver.nextAll(".montant_categorie:first").after(nouvelle_categorie);
		}
		nouvelle_categorie.after(montant_categorie);
	}
}

// permet d'ajouter un article à une categorie
// paramètres :
// - info_bloc : les infos du bloc (libelle et id)
// - info_categorie : les infos de la catégories (libelle et id)
// - article : l'ensemble des paramètres de l'articles passé sous forme de tableau associatif afin de rendre l'appel plus 'digeste'. Format :
// 	- id : l'id de l'article (unique)
// 	- code : le code de l'article ('' par défaut)
// 	- description : une description de l'article ('' par défaut)
// 	- quantite : la quantité pour cet article (1 par défaut)
// 	- prix : le prix de cet article (0 par défaut)
// 	- quantite_modifiable : boolean indiquant si la quantité est modifiable (true par défaut)
// 	- supprimable : boolean indiquant si la ligne est supprimable (true par défaut)
// - ajouterDeclencher : boolean indiquant si l'on doit déclencher les règles de type ligne/ligne
function ajouterArticle(info_bloc, info_categorie, article, ajouterDeclencher) {
	// on récupère les paramètres de l'article et on applique les valeurs par défaut en cas d'absence
	var id =					article.id; if(!id) alert("Erreur : absence de l'id dans l'appel de la fonction ajouterArticle"); // sécurité : l'id doit être présent !
	var code = 					(article.code == undefined ?	 			''		: article.code);
	var description = 			(article.description == undefined ?	 		''		: article.description);
	var quantite = 				(article.quantite == undefined ? 			1		: article.quantite);
	var quantite_initiale =		Math.ceil(quantite);
	var prix = 					(article.prix == undefined ? 				0		: article.prix);
	var quantite_modifiable = 	(article.quantite_modifiable == undefined ? true	: article.quantite_modifiable);
	var supprimable = 			(article.supprimable == undefined ? 		true	: article.supprimable);
	if(ajouterDeclencher == undefined) ajouterDeclencher = true;
	// quantité réel avec gestion des nombres à virgules
	if(liste_quantite_reel[id] == undefined) { liste_quantite_reel[id] = 0; }
	liste_quantite_reel[id] += quantite;
	quantite = Math.ceil(liste_quantite_reel[id]);
	
	// si la quantite est supérieur à 0, on ajoute bien l'élément
	// sinon, on tente de le supprimer
	if(quantite > 0) {
		// on essaye de voir si l'élément existe déjà
		var existe_deja = $('#quantite_article_' + id);
		if(existe_deja.length == 0) {
			// on crée la ligne avec les infos
			var ligne = $(
			'<tr class="ligne_article" name="categorie_'+info_categorie.libelle+'_article">'+
				'<td>'+code+
				'<input type="hidden" name="article['+id+'][code]" value="'+code+'" />'+
				'<input type="hidden" name="article['+id+'][description]" value="'+description+'" />'+
				'<input type="hidden" id="quantite_hidden_article_'+id+'" name="article['+id+'][quantite]" value="'+quantite+'" />'+
				'<input type="hidden" id="prix_article_'+id+'" name="article['+id+'][prix]" value="'+prix+'" />'+
				'<input type="hidden" name="article['+id+'][bloc]" value="'+info_bloc.id+'" />'+
				'<input type="hidden" name="article['+id+'][groupe]" value="'+info_categorie.id+'" /></td>'+
				'<td>'+description+'</td>'+
				'<td id="affichage_prix_article_'+id+'" name="prix_article">'+prix+' €</td>'+
				'<td name="quantite_article" id="quantite_article_'+id+'">'+quantite+'</td>'+
				'<td name="montant_article">'+(parseFloat(prix)*parseInt(quantite))+' €</td>'+
			'</tr>');
			
			// si l'article est supprimable, alors on ajoute de quoi supprimer la ligne
			if(supprimable) {
				var td_supprim = $('<td/>', {class:'cacher'});
				td_supprim.append($('<img/>', {src:'/img/delete.png', alt:'Supprimer cet article', title:'Supprimer cet article', click:function() {
					ligne.remove();
					mettreAJourPrixDevis();
					liste_quantite_reel[id] = 0;
				}}));
				ligne.append(td_supprim);
			}
			
			// si la quantité est modifiable, alors on ajoute l'événement voulut
			var en_modification = false; // permet de savoir si cette quantité est en train d'être modifié ou non
			if(quantite_modifiable) {
				var td_quantite = ligne.find("td[name='quantite_article']");
				td_quantite.attr('class', 'quantite_modifiable');
				td_quantite.click(function () {
					// si la quantité est déjà en train d'être modifié, on ne fait rien
					if(!en_modification) {
						en_modification = true;
						// un quantité de plus est en train d'être modifié
						nb_quantite_modifie++;
						// on récupère la précédente valeur pour la quantite
						var quantite = td_quantite.text();
						// on vide le td
						td_quantite.empty();
						// on ajoute deux input : un pour saisir le nombre, un pour valider la saisie
						var input_nombre = $('<input/>', {type:'number', class:'input_quantite', value:quantite, min:1, keydown:function(event){
							if(event.keyCode == 13) input_ok.click();
						}});
						var input_ok = $('<input/>', {type:'button', value:'ok', click:function(e) {
							// on vérifie que la quantité est correcte
							var nouvelle_quantite = parseInt(input_nombre.val());
							if(nouvelle_quantite == NaN || nouvelle_quantite < 1) alert("Ce n'est pas une quantité valide !");
							else {
								var difference = nouvelle_quantite - quantite;
								liste_quantite_reel[id] = nouvelle_quantite;
								// une quantité de moins est en train d'être modifié
								nb_quantite_modifie--;
								// on vide le td
								td_quantite.empty();
								// on met la nouvelle valeur en place
								td_quantite.text(nouvelle_quantite);
								// on met à jour le devis
								mettreAJourPrixDevis();
								// cette quantité n'est plus en modification
								en_modification = false;
								// on évite la reédition derrière on stoppant la propagation de l'évènement
								e.stopPropagation();
								ajouterArticlesDeclenches(id, difference);
								$('#quantite_hidden_article_'+id).val(nouvelle_quantite);
							}
						}});
						// on ajoute les input au td
						td_quantite.append(input_nombre);
						input_nombre.focus();
						td_quantite.append(input_ok);
					}
				});
			}
			
			// on récupère la catégorie dans le bon bloc
			var cat = $('#bloc_'+info_bloc.id+'_categorie_'+info_categorie.id);
			// on essaie de récupérer le dernier article de cette categorie
			// var emplacement = $("tr[name='categorie_" + nom_categorie + "_article']:last");
			// si on en a pas trouvé, alors on attrappe simplement la categorie
			// if(emplacement.length == 0) emplacement = $('#categorie_' + nom_categorie);
			// on insère la ligne après l'emplacement trouvé
			cat.after(ligne);
		}
		else {
			$('#quantite_hidden_article_'+id).val(quantite);
			existe_deja.text(quantite);
		}
		// on met à jour le montant total
		mettreAJourPrixDevis();
		
		if(ajouterDeclencher) ajouterArticlesDeclenches(id, quantite_initiale);
	}
	else {
		var existe_deja = $('#quantite_article_' + id);
		if(existe_deja.length > 0) existe_deja.parent().remove();
	}
}

// permet de mettre à jour le montant total pour une categorie
// paramètre :
// - id_categorie : l'id de la catégorie à mettre à jour
function mettreAJourPrixCategorie(id_categorie) {
	// variable contenant le montant total
	var montant_total = 0;
	// on récupère les lignes pour cette categorie
	var tr_categorie = $("tr[name='"+id_categorie+"_article']");
	tr_categorie.each(function (index, el) {
		var el_jquery = $(el);
		// pour chaque ligne, on calcul le montant à partir de la quantité et du prix
		var prix		= parseFloat(el_jquery.find("td[name='prix_article']").text());
		var quantite	= parseInt(el_jquery.find("td[name='quantite_article']").text());
		montant_total += parseInt((prix * quantite).toFixed(2));
		el_jquery.find("td[name='montant_article']").text((prix * quantite).toFixed(2) + ' €');
	});
	// on met à jour le montant avec la valeur calculé
	$('#montant_total_'+id_categorie+'').text(montant_total + ' €');
	// on retourne le montant total
	return montant_total;
}

// permet de mettre à jour le montant total du devis
function mettreAJourPrixDevis() {
	// on ne recalcule le devis que si aucune quantité n'est en train d'être modifié
	if(nb_quantite_modifie == 0) {
		var somme_totale = 0;
		// on récupère l'ensemble des blocs
		$('.bloc_devis').each(function (indice, el) {
			var jel = $(el);
			var somme_bloc = 0;
			// on récupère l'ensemble des sous-blocs
			jel.nextAll().each (function(indice, el) {
				var jel = $(el);
				if(jel.attr("name") == "categorie") {
					var somme = 0;
					// on récupère l'ensemble des articles
					jel.nextAll().each (function (indice, el) {
						var jel = $(el);
						// on s'arrête dés que l'on atteint une catégorie
						if(jel.filter('[name="categorie"]').length) return false;
						else if(jel.filter('.ligne_article').length) {
							var prix = parseFloat(jel.find('td[name="prix_article"]').text());
							var quantite = parseInt(jel.find('td[name="quantite_article"]').text());
							somme += prix * quantite;
							jel.find('td[name="montant_article"]').text((prix * quantite) + ' €');
						}
					});
					jel.nextAll('.montant_categorie:first').find('.total_devis').text(somme + ' €');
					somme_bloc += somme;
				}
				// on s'arrête si on à atteint le prochain bloc
				else if(jel.attr('class') == 'bloc_devis')
					return false;
			});
			somme_totale += somme_bloc;
			jel.nextAll('tr.montant_ht:first').find('td[name="montant_ht"]:first').text((somme_bloc).toFixed(2) + ' €');
			jel.nextAll('tr.tva:first').find('td[name="tva"]:first').text((somme_bloc / 100 * TVA).toFixed(2) + ' €');
			jel.nextAll('tr.montant_bloc:first').find('td[name="montant_bloc"]:first').text((somme_bloc / 100 * TVA + somme_bloc).toFixed(2) + ' €');
		});
		
		/*$('tr.montant_ht').find('td[name="montant_ht"]').text((somme_totale).toFixed(2) + ' €');
		$('tr.tva').find('td[name="tva"]').text((somme_totale / 100 * TVA).toFixed(2) + ' €');
		$('tr.montant_bloc').find('td[name="montant_bloc"]').text((somme_totale / 100 * TVA + somme_totale).toFixed(2) + ' €');*/
	}
}

// permet de mettre à jour la liste des catégories
// paramètres :
// - id_el_categorie : l'id de l'élément HTML de type select visant à contenir l'ensemble des catégories
// - id_el_article : l'id de l'élément HTML de type select visant à contenir l'ensemble des articles voulut
// - categories : un tableau contenant l'ensemble des catégories et leurs articles
function mettreAJourLesCategorieDArticle(id_el_categorie, id_el_article, categories) {
	// on récupère l'élément HTML puis on le vide de toute option, et enfin on rajoute une option vide
	var selectCategorie = $('#'+id_el_categorie);
	selectCategorie.empty();
	// on récupère l'élément HTML select pour les articles puis on le vide pour un futur traitement
	var selectArticle = $('#'+id_el_article);
	selectArticle.empty();
	
	// on parcours les catégories et on les affiches
	for (var k in categories) {
		selectCategorie.append($('<option/>', {text:categories[k].description_categorie, value:categories[k].id_categorie}));
	}
	// on rajoute l'évènement pour mettre à jour la liste des articles en fonction de la catégorie séléctionné
	selectCategorie.change(function() {
		var option = selectCategorie.find('option:selected');
		if(option.val() != '') {
			selectArticle.empty();
			for (var k in categories[option.val()].articles) {
				selectArticle.append($('<option/>', {value:categories[option.val()].articles[k].id_article, text:categories[option.val()].articles[k].description_article}));
			}
		}
	});
	
	// on appelle l'évènement 'change' pour mettre la valeur sur la première catégorie
	selectCategorie.change();
}

// fonction appelé lors du clic sur le bouton 'Ajouter un article'
// permet d'ajouter un article au formulaire temporaire
// paramètres :
// - id_categorie : l'id de la catégorie séléctionné
// - id_article : l'id de l'article séléctionné
// - categories : la structure complexe contenant l'ensemble des catégories et de leurs articles
function boutonAjouterArticle(id_categorie, id_article, categories) {
	// on vérifie que les ids sont bien valides en essayant de les convertir en entier
	if(parseInt(id_categorie) != NaN && parseInt(id_article) != NaN) {
		var art = categories[id_categorie].articles[id_article];
		// ajout du bloc de l'article
		ajouterBloc(art.bloc.id_bloc_devis, art.bloc.libelle_bloc_devis, art.bloc.rang_bloc_devis);
		// ajout de la categorie de l'article
		ajouterCategorie(art.groupe.id_groupe_devis, art.groupe.libelle_groupe_devis, art.bloc.id_bloc_devis, art.bloc.libelle_bloc_devis, art.groupe.rang_groupe_devis, art.bloc.rang_bloc_devis);
		// ajout de l'article dans la catégorie autre
		ajouterArticle({id:art.bloc.id_bloc_devis, libelle:art.bloc.libelle_bloc_devis},
						{id:art.groupe.id_groupe_devis, libelle:art.groupe.libelle_groupe_devis},
						{code:art.ref_article, description:art.description_article, prix:art.tarif_brut, id:art.id_article})
	}
}

function acceptation_validation_devis() {
	if(confirm("ATTENTION : cette action validera le devis.\nLe revendeur ne pourra plus le modifier et pourra le générer en PDF.\nSouhaitez-vous continuer ?")) {
		return true;
	}
	return false;
}

function accepterDevis() {
	if(confirm("Le devis est accepté par le client et sera archivé.\nVous aurez toujours la possibilité de voir ce devis et de récupérer son format PDF.\nSouhaitez-vous continuer ?")) {
		return true;
	}
	return false;
}

function refuserDevis() {
	if(confirm("Le devis est refusé par le client et sera archivé.\nVous aurez toujours la possibilité de voir ce devis et de récupérer son format PDF.\nSouhaitez-vous continuer ?")) {
		return true;
	}
	return false;
}